package com.inspur.edp.formserver.vmmanager.helpconfig;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.JsonNodeType;
import com.inspur.edp.cef.designtime.api.util.Guid;
import com.inspur.edp.formserver.viewmodel.action.MappedCdpAction;
import com.inspur.edp.formserver.viewmodel.action.mappedcdp.MappedCdpActionParameter;
import com.inspur.edp.formserver.viewmodel.action.viewmodelbase.ViewModelParActualValue;
import com.inspur.edp.formserver.viewmodel.action.viewmodelbase.ViewModelParameter;
import com.inspur.edp.formserver.viewmodel.collection.VMActionCollection;
import com.inspur.edp.formserver.viewmodel.common.VMParameterMode;
import com.inspur.edp.formserver.viewmodel.common.ValueHelpConfig;
import com.inspur.edp.formserver.vmmanager.util.CheckInfoUtil;
import com.inspur.edp.lcm.metadata.api.service.MdpkgService;
import io.iec.edp.caf.commons.utils.SpringBeanUtils;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.UUID;

public class HelpConfigFilterSortHandler {

  public static final String SORT_FILTER_CMPID = "07156c90-f6ee-4d1b-ad57-a40e4027c50c";
  public static final String FILTER_CONDITION_PROPERTY = "filterCondition";
  public static final String SORT_CONDITION_PROPERTY = "orderByCondition";
  public static final String COMMON_CMP_PKGNAME = "Inspur.Gsp.Common.CommonCmp.mdpkg";

  private MdpkgService mdpkgService;

  private MdpkgService getMdpkgService() {
    if (mdpkgService == null) {
      this.mdpkgService = SpringBeanUtils.getBean(MdpkgService.class);
    }
    return this.mdpkgService;
  }

  private HashMap<String, MappedCdpAction> actionMap;
  private ValueHelpConfig config;
  private String metaPath;

  public HelpConfigFilterSortHandler(ValueHelpConfig config, String path) {

    this.config = config;
    this.metaPath = path;
  }

  public HelpConfigFilterSortHandler(ValueHelpConfig config) {
    this.config = config;
  }

  public static HelpConfigFilterSortHandler getInstance(ValueHelpConfig config, String path) {
    return new HelpConfigFilterSortHandler(config, path);
  }

  public static HelpConfigFilterSortHandler getInstance(ValueHelpConfig config) {
    return new HelpConfigFilterSortHandler(config);
  }
  /**
   * 处理帮助配置中的过滤排序
   */
  public void handleConfigFilterAndSort(String newFilterCondition, String newSortCondition
  ) {
    // 无过滤条件且无排序条件,删除对应Action
    if (isConditionNull(newSortCondition) && isConditionNull(newFilterCondition)) {
      MappedCdpAction action = getCurrentAction();
      if (action != null) {
        config.getHelpExtend().getBeforeHelp().remove(action);
      }
      return;
    }
    // 有条件，无Action，新增对应Action
    if (getCurrentAction() == null) {
      VMActionCollection currentActions = config.getHelpExtend().getBeforeHelp().clone();
      config.getHelpExtend().getBeforeHelp().clear();
      config.getHelpExtend().getBeforeHelp()
          .add(getHelpVOAction(config, newFilterCondition, newSortCondition));
      config.getHelpExtend().getBeforeHelp().addAll(currentActions);
      // 添加元数据包引用
      addMetadataPkgDependency(metaPath);
      return;
    }
    // 已有Action,赋值对应属性
    getCurrentAction().getParameterCollection().forEach(item -> {
      ViewModelParameter para = (ViewModelParameter) item;
      switch (para.getParamCode()) {
        case FILTER_CONDITION_PROPERTY:
          para.getActualValue().setValue(newFilterCondition);
          break;
        case SORT_CONDITION_PROPERTY:
          para.getActualValue().setValue(newSortCondition);
          break;
      }
    });
  }


  public void handleRtConfigFilterAndSort(String newFilterCondition, String newSortCondition
  ) {
    // 无过滤条件且无排序条件,删除对应Action
    if (isConditionNull(newSortCondition) && isConditionNull(newFilterCondition)) {
      MappedCdpAction action = getCurrentAction();
      if (action != null) {
        config.getHelpExtend().getBeforeHelp().remove(action);
      }
      return;
    }
    // 有条件，无Action，新增对应Action
    if (getCurrentAction() == null) {
      VMActionCollection currentActions = config.getHelpExtend().getBeforeHelp().clone();
      config.getHelpExtend().getBeforeHelp().clear();
      config.getHelpExtend().getBeforeHelp()
          .add(getHelpVOAction(config, newFilterCondition, newSortCondition));
      config.getHelpExtend().getBeforeHelp().addAll(currentActions);
      // 添加元数据包引用
      //addMetadataPkgDependency(metaPath);
      return;
    }
    // 已有Action,赋值对应属性
    getCurrentAction().getParameterCollection().forEach(item -> {
      ViewModelParameter para = (ViewModelParameter) item;
      switch (para.getParamCode()) {
        case FILTER_CONDITION_PROPERTY:
          para.getActualValue().setValue(newFilterCondition);
          break;
        case SORT_CONDITION_PROPERTY:
          para.getActualValue().setValue(newSortCondition);
          break;
      }
    });
  }
  private MappedCdpAction getCurrentAction() {
    if (actionMap == null) {
      actionMap = new HashMap<>();
      MappedCdpAction action = (MappedCdpAction) config.getHelpExtend().getBeforeHelp()
          .getItem(item -> (item instanceof MappedCdpAction) && ((MappedCdpAction) item)
              .getComponentEntityId().equals(SORT_FILTER_CMPID));
      actionMap.put(config.getElementId(), action);
    }
    return actionMap.get(config.getElementId());
  }

  /**
   * 过滤排序条件是否为空
   */
  private Boolean isConditionNull(String currentSort) {
    try {
      if (CheckInfoUtil.checkNull(currentSort)) {
        return true;
      }
      ObjectMapper objectMapper = new ObjectMapper();
      JsonNode nodeList = objectMapper.readTree(currentSort);
      if (nodeList.getNodeType() != JsonNodeType.ARRAY) {
        return true;
      }
      return nodeList.size() == 0;
    } catch (JsonProcessingException e) {
      throw new RuntimeException(e);
    }
  }

  /**
   * 添加元数据包引用
   */
  private void addMetadataPkgDependency(String path) {
    if (CheckInfoUtil.checkNull(path)) {
      return;
    }
    ArrayList<String> list = new ArrayList<String>();
    list.add(COMMON_CMP_PKGNAME);
    this.getMdpkgService().addDepedencyAndRestore(path, list);
  }

  /**
   * 新增过滤排序Action
   */
  private MappedCdpAction getHelpVOAction(ValueHelpConfig valueHelpConfig, String filterCondition,
      String sortCondition) {
    MappedCdpAction mappedCdpAction = new MappedCdpAction();
    mappedCdpAction.setIsGenerateComponent(false);
    if (valueHelpConfig.getHelpExtend().getBeforeHelp().isEmpty()) {
      mappedCdpAction.setID(Guid.newGuid().toString());
    }
    String originalKey = valueHelpConfig.getElementId(); //此ID分两段，用/区分
    String[] info = originalKey.split("[/]", -1);
    if (info.length != 2) {
      throw new RuntimeException("ValueHelpConfig对象的ElementId字段不符合约定");
    }
    mappedCdpAction.setCode(info[1]);
    mappedCdpAction.setName(info[1]);
    mappedCdpAction.setComponentEntityId(SORT_FILTER_CMPID);
    mappedCdpAction.setComponentName("VO帮助前支持过滤筛选构件");

    MappedCdpActionParameter filterParameter = getPara(FILTER_CONDITION_PROPERTY,
        FILTER_CONDITION_PROPERTY);
    ViewModelParActualValue filterValue = new ViewModelParActualValue();
    filterValue.setHasValue(true);
    filterValue.setEnable(true);
    filterValue.setValue(filterCondition);
    filterParameter.setActualValue(filterValue);
    mappedCdpAction.getParameterCollection().add(filterParameter);

    MappedCdpActionParameter orderByParameter = getPara(SORT_CONDITION_PROPERTY,
        SORT_CONDITION_PROPERTY);
    ViewModelParActualValue orderByValue = new ViewModelParActualValue();
    orderByValue.setHasValue(true);
    orderByValue.setEnable(true);
    orderByValue.setValue(sortCondition);
    orderByParameter.setActualValue(orderByValue);
    mappedCdpAction.getParameterCollection().add(orderByParameter);

    return mappedCdpAction;
  }

  private MappedCdpActionParameter getPara(String code, String name) {
    MappedCdpActionParameter para = new MappedCdpActionParameter();
    para.setID(UUID.randomUUID().toString());
    para.setParamName(name);
    para.setParamCode(code);
    para.setMode(VMParameterMode.IN);
    return para;
  }

}
